<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>545在线-帅比笙歌超可爱OvO-播放器-在线听歌-下载音频</title>
    <meta name="description" content="545在线，电子雷峰塔，随时补充塔能量！笙歌牌播放器，采用PWA技术，支持智能缓存本地播放，可完全断网使用，由琴梨梨驱动" />
    <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
    <link rel="canonical" href="https://545.qinlili.bid/" />
    <link rel="manifest" href="./manifest.json">
    <meta name="theme-color" content="#FADCBB">
    <link rel="icon" href="./icon_mono.png">
    <link rel="apple-touch-icon" href="./icon_badminton_mask_small.png">
    <meta name="apple-mobile-web-app-title" content="545在线">
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="apple-touch-fullscreen" content="yes" />
    <meta name="apple-mobile-web-app-status-bar-style" content="default" />
    <meta name="referrer" content="no-referrer" />
    <link rel="preconnect" href="https://i0.hdslb.com">
    <link rel="preconnect" href="https://bj.bcebos.com">
    <link rel="preconnect" href="https://cdn-cf.545.qinlili.bid">
    <script>
        document.title = "载入播放器中...";
        window.Castjs = false;
        window.cjsplay = false;
    </script>
    <link crossorigin="anonymous"
        integrity="sha512-tH5CEoO7QorGJK5RZrcKozo5xe0qC0UgOhjkIoqXNVe9ApFAjJRbVFzDfVvdRUSOJ5g2Pw9VzzOBguouzhLoIQ=="
        href="https://lib.baomitu.com/material-components-web/6.0.0/material-components-web.min.css" rel="stylesheet">
    <script crossorigin="anonymous"
        integrity="sha512-5zCl3JhN4Fqq6+irTX1v8J+77hwL54zTbrdl2Dl8YHe+KGcuV14C01u/uWFrSg+kZgOfGMneoUySVHqEgdRaPQ=="
        src="https://lib.baomitu.com/material-components-web/6.0.0/material-components-web.min.js"></script>
    <link crossorigin="anonymous" href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <script src="./lib/hamood.min.js"></script>
    <script defer src="./lib/cast.min.js" onload="initCast();"></script>
    <style>
        @keyframes leftin {
            from {
                margin-left: -100%;
            }

            to {
                margin-left: 0;
            }
        }

        @keyframes rightin {
            from {
                margin-left: 100%;
            }

            to {
                margin-left: 0;
            }
        }

        @keyframes bottomup {
            from {
                bottom: -100%;
            }

            to {
                bottom: 0;
            }
        }

        @keyframes bottomdown {
            from {
                bottom: 0;
            }

            to {
                bottom: -100%;
            }
        }
    </style>
    <style>
        audio::-webkit-media-controls-enclosure {
            background: transparent;
            border-radius: 0px;
        }

        audio::-webkit-media-controls-panel {
            border-radius: 0px;
        }

        audio.player::class(controlBar) {
            background-color: transparent;
        }

        ::-webkit-scrollbar {
            border-top: 4px solid rgba(0, 0, 0, 0);
            border-bottom: 4px solid rgba(0, 0, 0, 0);
            width: 8px;
            background: transparent;
            z-index: 12;
            overflow: visible;
        }

        ::-webkit-scrollbar-thumb {
            border-top: 4px solid rgba(0, 0, 0, 0);
            border-bottom: 4px solid rgba(0, 0, 0, 0);
            width: 4px;
            background-color: #FADCBB;
            border-left: 4px solid rgba(0, 0, 0, 0);
            background-clip: padding-box;
        }

        ::-webkit-scrollbar-thumb:hover {
            background: #FADCBB;
        }

        ::-webkit-scrollbar-corner {
            background: #202020;
        }

        *:focus {
            outline: none;
        }

        * {
            -webkit-tap-highlight-color: transparent;
            scrollbar-width: thin;
            scrollbar-color: #FADCBB transparent;
            --mdc-theme-primary: #DCAC89;
            --mdc-theme-secondary: #FADCBB;
            box-sizing: border-box;
            margin: 0;
            padding: 0;
            -webkit-user-select: none;
            user-select: none;
        }


        html,
        body {
            position: fixed;
            overflow: hidden;
            width: 100vw;
            height: 100%;
        }

        .liveFrame {
            width: 80vw;
            height: 45vw;
            max-height: 80vh;
        }

        #playPanel {
            backdrop-filter: blur(5px) brightness(100%);
            -webkit-backdrop-filter: blur(5px) brightness(100%);
            background-color: rgba(255, 255, 255, 0.75);
            animation: bottomup 0.3s;
            z-index: 999;
            position: fixed;
            height: auto;
            min-height: 32px;
            width: auto;
            left: 0px;
            right: 0px;
            bottom: 0px;
            padding-top: 2px;
            padding-bottom: 2px;
            box-shadow: 0px -2px 2px 1px rgba(0, 0, 0, 0.5);
            display: flex;
            flex-direction: column;
        }

        #listContainer {
            overflow: hidden;
            height: 100%;
        }

        #audioList,
        #playList {
            width: 100vw;
            text-align: left;
            overflow-y: auto;
            height: calc(100% - 48px);
            padding-bottom: 100px;
            transition: width 0.2s ease-in;
            position: relative;
        }

        #playList {
            animation: leftin 0.2s;
        }

        #audioList {
            animation: rightin 0.2s;
        }

        #menuList {
            display: flex;
            flex-direction: column;
        }

        #audioFolderModule,
        #audioFilesModule {
            transition: transform 0.2s ease-out;
            position: absolute;
            width: 100%;
            padding-bottom: 100px !important;
        }

        #audioFolderModule {
            transform-origin: left;
            transform: scale(1, 1);
        }

        #audioFilesModule {
            transform-origin: right;
            display: none;
            transform: scale(0, 1);
        }

        #tabBar {
            z-index: 999;
            position: fixed;
            height: auto;
            width: auto;
            left: 0px;
            right: 0px;
            top: 0px;
        }

        #empty {
            display: none;
            margin: auto;
            padding-top: 32px;
            height: auto;
            text-align: center;
        }

        .controls {
            justify-content: space-between;
            display: flex;
            flex-direction: row;
            padding-left: 2px;
            padding-right: 2px;
        }

        #status {
            display: flex;
            flex-direction: row;
            height: 32px;
            padding-left: 4px;
            max-width: calc(100vw - 140px);
        }

        #tips,
        .tips32 {
            margin: auto;
            font-size: 1.1em;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            flex-shrink: 0;
        }

        #loading {
            width: 32px;
            margin: 0px;
        }

        .buttons {
            display: flex;
            flex-direction: row;
        }

        .topBtn {
            cursor: pointer;
            border-radius: 2px;
            height: 24px;
            margin: 4px;
            width: 24px;
            transition: background-color 0.2s, transform 0.3s ease-in-out;
        }

        .topBtn:hover {
            transform: scale(1.1, 1.1);
            background-color: #cccccc;
        }

        .topBtn:active {
            background-color: #999999;
        }

        .topBtn.active {
            background-color: #FADCBB;
        }

        @keyframes breath {
            from {

                background-color: #FADCBB;
            }

            to {
                background-color: #FFFFFF;
            }
        }

        .topBtn.breath {
            animation: breath 0.25s infinite alternate;
        }

        #padding {
            height: 48px;
        }

        #floatMenuContainer {
            transition: opacity 0.2s ease-in;
            opacity: 0;
            display: none;
            z-index: 9999;
            top: 0px;
            bottom: 0px;
            left: 0px;
            right: 0px;
            height: auto;
            width: auto;
            position: fixed;
            background-color: rgba(0, 0, 0, 0.25);
        }

        #floatMenu {
            box-shadow: rgb(0 0 0 / 25%) 0px 4px 20px 1px;
            transform: scale(0.1, 0.1);
            transform-origin: left top;
            overflow-y: auto;
            width: 80%;
            max-height: 0px;
            border-radius: 4px;
            backdrop-filter: blur(5px) brightness(100%);
            -webkit-backdrop-filter: blur(5px) brightness(100%);
            background-color: rgba(255, 255, 255, 0.75);
        }

        .mdc-list {
            padding: 0 0 !important;
        }

        .material-icons {
            background-repeat: round;
        }

        .material-icons {
            display: flex;
        }

        @media (min-width: 700px) {
            #listContainer {
                display: flex !important;
                flex-direction: row-reverse !important;
            }

            #padding {
                height: 0px;
            }

            #audioList,
            #playList {
                height: 100%;
                display: block !important;
                width: 50vw;
            }

            #tabBar {
                display: none;
            }

            #floatMenu {
                max-width: 400px;
            }

            .liveFrame {
                max-width: 400px;
                max-height: 225px;
            }
        }

        @media (hover: hover) {
            audio {
                cursor: url("/cursor/1.webp"), auto !important;
            }

            @keyframes cursor {
                0% {
                    cursor: url("/cursor/1.webp"), auto;
                }

                10% {
                    cursor: url("/cursor/2.webp"), auto;
                }

                20% {
                    cursor: url("/cursor/3.webp"), auto;
                }

                30% {
                    cursor: url("/cursor/4.webp"), auto;
                }

                40% {
                    cursor: url("/cursor/5.webp"), auto;
                }

                50% {
                    cursor: url("/cursor/6.webp"), auto;
                }

                60% {
                    cursor: url("/cursor/7.webp"), auto;
                }

                70% {
                    cursor: url("/cursor/8.webp"), auto;
                }

                80% {
                    cursor: url("/cursor/9.webp"), auto;
                }

                90% {
                    cursor: url("/cursor/10.webp"), auto;
                }

                100% {
                    cursor: url("/cursor/1.webp"), auto;
                }

            }

            div *:not(audio) {
                cursor: inherit !important;
            }

            body {
                animation: cursor 1s infinite;
            }
        }
    </style>
</head>

<body style="text-align: center">
    <div class="mdc-tab-bar" id="tabBar" role="tablist">
        <div class="mdc-tab-scroller">
            <div class="mdc-tab-scroller__scroll-area">
                <div class="mdc-tab-scroller__scroll-content">
                    <button class="mdc-tab mdc-tab--active" role="tab" aria-selected="true" tabindex="0"
                        onclick="switchPlaylist();">
                        <span class="mdc-tab__content">
                            <span class="mdc-tab__text-label">播放列表</span>
                        </span>
                        <span class="mdc-tab-indicator mdc-tab-indicator--active">
                            <span class="mdc-tab-indicator__content mdc-tab-indicator__content--underline"></span>
                        </span>
                        <span class="mdc-tab__ripple"></span>
                    </button>
                    <button class="mdc-tab mdc-tab" role="tab" aria-selected="false" tabindex="-1"
                        onclick="switchAudioList();">
                        <span class="mdc-tab__content">
                            <span class="mdc-tab__text-label">全部歌单</span>
                        </span>
                        <span class="mdc-tab-indicator mdc-tab-indicator">
                            <span class="mdc-tab-indicator__content mdc-tab-indicator__content--underline"></span>
                        </span>
                        <span class="mdc-tab__ripple"></span>
                    </button>
                </div>
            </div>
        </div>
    </div>
    <div id="playPanel">
        <div id="controls" class="controls">
            <div id="status">
                <img src="./img/loading.webp" id="loading">
                <p id="tips">正在加载播放器</p>
            </div>
            <div id="buttons" class="buttons">
                <p class="topBtn" id="castBtn" onclick="switchCast();" alt="Chromecast" tabindex="-1"
                    style="background-image: url(./img/cast.svg)">
                <p class="topBtn" id="shuffleBtn" onclick="switchShuffle();" alt="随机播放" tabindex="-1"
                    style="background-image: url(./img/shuffle.svg)">
                <p class="topBtn" id="repeatBtn" onclick="switchRepeat();" alt="循环播放" tabindex="-1"
                    style="background-image: url(./img/repeat.svg)">
                <p class="topBtn" id="settingBtn" onclick="functionMenu()" alt="菜单" tabindex="-1"
                    style="background-image: url(./img/menu.svg)">
            </div>
        </div>
        <audio controls autoplay id="player" style="width: 100%;height:32px;"></audio>
        <div id="backupControls" class="controls" style="display:none;">
            <div id="backupButtons" class="buttons">
                <img class="topBtn" id="playBtn" loading="lazy" onclick="switchPlay();" alt="播放" src="./img/play.svg">
                <img class="topBtn" id="nextBtn" loading="lazy"
                    onclick="player.dispatchEvent(new CustomEvent('ended'));" alt="下一曲" src="./img/next.svg">
            </div>
        </div>
    </div>
    <div id="padding"></div>
    <div id="listContainer">
        <div id="audioList" style="display:none;">
            <ul id="audioFolderModule" class="mdc-list mdc-list--two-line mdc-list--avatar-list">
            </ul>
            <ul id="audioFilesModule" class="mdc-list mdc-list--two-line mdc-list--avatar-list">
            </ul>
        </div>
        <div id="playList">
            <div id="empty">
                <img src="./img/bai.png">
                <H2>播放列表空了,所以摆了</H2>
                <H3>去全部歌单里添加一些吧</H3>
            </div>
            <ul id="audioListModule" class="mdc-list mdc-list--two-line mdc-list--avatar-list">
            </ul>
        </div>
    </div>
    <div id="floatMenuContainer">
        <div id="floatMenu">
            <ul class="mdc-list" id="menuList">

            </ul>
        </div>
    </div>
    <script>
        if (localStorage.disableAnim ? JSON.parse(localStorage.disableAnim) : false) {
            var style = document.createElement('style');
            style.type = 'text/css';
            style.rel = 'stylesheet';
            style.appendChild(document.createTextNode(`*{transition:none !important;}`));
            document.getElementsByTagName('head')[0].appendChild(style);
        };
        (() => {
            if ((localStorage.skipSplash ? JSON.parse(localStorage.skipSplash) : false) || !(window.self === window.top)) {
                return;
            };
            const hamoodConfig = {
                data: "./hamood.json?ForceNoCache=1",
                forceSkipPreload: true,
                showLoadingTip: true
            }
            Hamood.init(hamoodConfig, false);
        })();
        window.isBiliLite = false;
        window.list = [];
        const $ = text => {
            if (text == '.h5-download-bar') {
                window.isBiliLite = true;
                const biliLiteHook = { hide: () => { console.log("BiliLite detected, enable extension functions...") } };
                return biliLiteHook;
            }
        }
        const loadScriptAsync = link => {
            return new Promise(resolve => {
                let script = document.createElement("script");
                script.src = link;
                script.onload = resolve;
                document.body.appendChild(script);
            });
        }
        const sleep = delay => new Promise((resolve) => setTimeout(resolve, delay))
        window.MDCTabBar = mdc.tabBar.MDCTabBar;
        window.MDCList = mdc.list.MDCList;
        window.MDCRipple = mdc.ripple.MDCRipple;
        const tabBar = new MDCTabBar(document.querySelector('.mdc-tab-bar'));
        const audioList = document.getElementById("audioList");
        const playList = document.getElementById("playList");
        const switchAudioList = () => {
            audioList.style.display = "block"
            playList.style.display = "none"
        }
        const switchPlaylist = () => {
            audioList.style.display = "none"
            playList.style.display = "block"
        }
        const random = (min, max) => {
            return Math.round(Math.random() * (max - min)) + min;
        }
        const dlFile = (link, name) => {
            let eleLink = document.createElement('a');
            eleLink.download = name;
            eleLink.style.display = 'none';
            eleLink.href = link;
            document.body.appendChild(eleLink);
            eleLink.click();
            document.body.removeChild(eleLink);
        }
        const bottomdown = () => {
            document.getElementById("playPanel").style.animation = "bottomdown 0.5s";
            setTimeout(() => {
                document.getElementById("playPanel").style.animation = "";
                document.getElementById("playPanel").style.display = "none";
            }, 450);
        }
        window.addEventListener('pageshow', (event) => {
            if (event.persisted) {
                console.log('This page was restored from the bfcache.');
                setTimeout(() => {
                    document.getElementById("playPanel").style.display = "flex";
                    document.getElementById("playPanel").style.animation = "bottomup 0.5s";
                }, 450);
            }
        });
    </script>
    <script>
        const cdn = localStorage.preferCDN ? localStorage.preferCDN : "yuketang";
        window.repeatSwitch = localStorage.repeat ? JSON.parse(localStorage.repeat) : false;
        window.shuffleSwitch = localStorage.shuffle ? JSON.parse(localStorage.shuffle) : false;
        window.codecBoost = localStorage.codecBoost ? JSON.parse(localStorage.codecBoost) : false;
        window.wasmPlayer = localStorage.wasmPlayer ? JSON.parse(localStorage.wasmPlayer) : false;
        window.fileShare = localStorage.fileShare ? JSON.parse(localStorage.fileShare) : false;
        window.clientLive = localStorage.clientLive ? JSON.parse(localStorage.clientLive) : false;
        window.devMode = localStorage.erudaEnabled ? JSON.parse(localStorage.erudaEnabled) : false;
        window.castSwitch = false;
        window.ignoreNextCastEnd = false;
        if (repeatSwitch) {
            document.getElementById("repeatBtn").className = "topBtn active";
        };
        if (shuffleSwitch) {
            document.getElementById("shuffleBtn").className = "topBtn active";
        };
        const initCast = () => {
            window.cjsplay = new Castjs();
            cjsplay.on('playing', () => {
                player.pause();
                ignoreNextCastEnd = false;
                setStatus("推送成功:" + currentPlay);
                document.getElementById("castBtn").className = "topBtn active";
            });
            cjsplay.on('disconnect', () => {
                setStatus("连接已断开");
                window.castSwitch = false;
                document.getElementById("castBtn").className = "topBtn";
            });
            cjsplay.on('end', () => {
                setStatus("播放已结束，推送下一首...");
                if (!ignoreNextCastEnd) {
                    player.dispatchEvent(new CustomEvent('ended'));
                }
            });
        };
        const switchCast = async () => {
            if (window.castSwitch) {
                //结束投屏
                cjsplay.disconnect();
            } else {
                //开始投屏
                if (!Castjs) {
                    setStatus("Chromecast模块尚未就绪，再等等");
                    return false;
                }
                setStatus("正在寻找设备", true);
                if (cjsplay.available) {
                    window.castSwitch = true;
                    setStatus("连接中", true);
                    let song = JSON.parse(localStorage.lastPlay)
                    playNow(song);
                } else {
                    cjsplay.on('available', () => {
                        window.castSwitch = true;
                        setStatus("连接中", true);
                        let song = JSON.parse(localStorage.lastPlay)
                        playNow(song);
                    });
                }
            }
        };
        const switchRepeat = () => {
            window.repeatSwitch = repeatSwitch ? false : true;
            localStorage.repeat = window.repeatSwitch;
            document.getElementById("repeatBtn").className = window.repeatSwitch ? "topBtn active" : "topBtn";
        };
        const switchShuffle = () => {
            window.shuffleSwitch = shuffleSwitch ? false : true;
            localStorage.shuffle = window.shuffleSwitch;
            document.getElementById("shuffleBtn").className = window.shuffleSwitch ? "topBtn active" : "topBtn";
        };
        const switchPlay = () => {
            if (window.wasmPlayer) {
                document.getElementById("playBtn").className = document.querySelector("#player").paused ? "topBtn active" : "topBtn";
                document.querySelector("#player").paused ? document.querySelector("#player").play() : document.querySelector("#player").pause()
            };
            if (window.codecBoost) {
                document.getElementById("playBtn").className = (audioCtx.state == "running") ? "topBtn" : "topBtn active";
                (audioCtx.state == "running") ? audioCtx.suspend() : audioCtx.resume();
            };
        }
        const useBackupControl = () => {
            window.backupControl = true;
            player.style.display = "none";
            document.getElementById("backupControls").style.display = "flex";
            player.addEventListener("play", () => {
                document.getElementById('playBtn').className = 'topBtn active';
            });
            player.addEventListener("pause", () => {
                document.getElementById('playBtn').className = 'topBtn';
            });
        }
        const menuList = document.getElementById("menuList");
        if (localStorage.fullBlur && JSON.parse(localStorage.fullBlur)) {
            document.getElementById("floatMenuContainer").style.backdropFilter = "blur(3px) brightness(100%)";
            document.getElementById("floatMenuContainer").setAttribute("style", document.getElementById("floatMenuContainer").getAttribute("style") + "-webkit-backdrop-filter:blur(3px) brightness(100%)");

        };
        //指尖跟随菜单
        window.lastClick = { x: 0, y: 0 };
        window.lastClickMenu = { x: 0, y: 0 };
        window.addEventListener('pointerdown', (event) => {
            if (!(document.getElementById("floatMenuContainer").style.display == "block")) {
                lastClick.x = event.clientX;
                lastClick.y = event.clientY;
            } else {
                lastClickMenu.x = event.clientX;
                lastClickMenu.y = event.clientY;
            }
        });
        const locateMenu = () => {
            //大屏随动菜单
            if (document.body.clientWidth >= 700) {
                //右侧有空间
                if (document.body.clientWidth - 400 > lastClick.x) {
                    document.getElementById("floatMenu").style.marginLeft = lastClick.x + "px";
                } else {
                    document.getElementById("floatMenu").style.marginLeft = document.body.clientWidth - 400 + "px";
                };
                if (document.body.clientHeight - document.getElementById("floatMenu").scrollHeight > lastClick.y) {
                    document.getElementById("floatMenu").style.marginTop = lastClick.y + "px";
                } else {
                    if (document.body.clientHeight - document.getElementById("floatMenu").scrollHeight < 0) {
                        document.getElementById("floatMenu").style.marginTop = document.body.clientHeight * 0.1 + "px";
                    } else {
                        document.getElementById("floatMenu").style.marginTop = document.body.clientHeight - document.getElementById("floatMenu").scrollHeight + "px";
                    }
                }
            } else {
                document.getElementById("floatMenu").style.marginLeft = "10%";
                document.getElementById("floatMenu").style.marginTop = document.body.clientHeight * 0.1 + "px";
            }
        };
        const showMenu = async () => {
            if (document.getElementById("floatMenuContainer").style.display == "block") { return true; }
            document.getElementById("floatMenuContainer").style.display = "block";
            document.getElementById("floatMenu").style.overflowY = "hidden";
            document.getElementById("floatMenu").style.marginLeft = lastClick.x + "px";
            document.getElementById("floatMenu").style.marginTop = lastClick.y + "px";
            document.getElementById("floatMenu").style.transition = "all 0.3s";
            await sleep(5);
            document.getElementById("floatMenuContainer").style.opacity = 1;
            locateMenu()
            document.getElementById("floatMenu").style.transform = "scale(1,1)";
            await sleep(295);
            document.getElementById("floatMenu").style.overflowY = "auto";
            if (window.CloseWatcher) {
                window.MenuBack = new CloseWatcher();
                MenuBack.onclose = () => {
                    lastClickMenu = lastClick;
                    hideMenu();
                };
            }
        };
        const hideMenu = async () => {
            document.getElementById("floatMenu").style.transform = "scale(0.1, 0.1)";
            document.getElementById("floatMenu").style.marginLeft = lastClickMenu.x + "px";
            document.getElementById("floatMenu").style.marginTop = lastClickMenu.y + "px";
            document.getElementById("floatMenuContainer").style.opacity = 0;
            await sleep(300);
            document.getElementById("floatMenuContainer").style.display = "none";
            menuList.innerHTML = "";
            document.getElementById("floatMenu").style.transition = "max-height 0.3s linear";
            if (window.CloseWatcher) {
                window.MenuBack.destroy();
            }
        };
        window.addEventListener("resize", async (event) => {
            if (document.getElementById("floatMenuContainer").style.display == "block") {
                await sleep(100);
                resizeMenu();
            };
        });
        document.getElementById("floatMenuContainer").addEventListener("click", (event) => {
            event.stopPropagation();
            hideMenu();
        })
        //菜单魔法展开
        const resizeMenu = () => {
            let contentHeight = document.getElementById("floatMenu").scrollHeight;
            document.getElementById("floatMenu").style.height = "auto";
            let originHeight = document.getElementById("floatMenu").style.maxHeight;
            let maxHeight = document.body.clientHeight * 0.8;
            if (contentHeight > maxHeight) {
                contentHeight = maxHeight;
                document.getElementById("floatMenu").style.marginTop = document.body.clientHeight * 0.1 + "px";
                document.getElementById("floatMenu").style.overflowY = "auto";
            } else {
                document.getElementById("floatMenu").style.overflowY = "hidden";
            }
            document.getElementById("floatMenu").style.maxHeight = (contentHeight) + "px";
            if (parseInt(originHeight) > contentHeight) {
                document.getElementById("floatMenu").style.height = originHeight;
            };
            locateMenu();
        }
        const observer = new MutationObserver(resizeMenu);
        observer.observe(document.getElementById("floatMenu"), { childList: true, subtree: true, attributes: true, attributeFilter: ['loaded'] });
        const setStatus = (text, loading) => {
            document.getElementById("loading").style.display = loading ? "block" : "none";
            document.getElementById("tips").innerText = text;
        };
        const setTempStatus = (text, time) => {
            document.getElementById("loading").style.display = "none";
            let currentText = document.getElementById("tips").innerText;
            setTimeout(() => { document.getElementById("tips").innerText = currentText }, time);
            document.getElementById("tips").innerText = text;
        }
        let player = document.getElementById("player");
        (async () => {
            if (window.codecBoost && window.wasmPlayer) {
                alert("播放器初始化失败！\n请勿同时启用Codec Boost和WASM播放器！");
                bottomdown();
                document.location.href = './settings';
                return;
            }
            if (window.wasmPlayer) {
                setStatus("加载WASM播放器", true);
                await loadScriptAsync("./lib/ogvjs/ogv.js");
                document.getElementById("playPanel").removeChild(player);
                player = new ogvjs.OGVPlayer();
                player.controls = true;
                player.autoplay = true;
                player.id = "player";
                player.style = "width: 100%;height:32px;";
                document.getElementById("playPanel").appendChild(player);
                useBackupControl();
                patchEnd();
                setStatus("就绪");
                document.title = "545在线";
                return;
            };
            if (window.codecBoost) {
                useBackupControl();
                return;
            };
        })();
        //初始化媒体控制
        if ('mediaSession' in navigator) {
            navigator.mediaSession.setActionHandler('play', function () {
                if (window.backupControl) {
                    switchPlay();
                } else {
                    player.play();
                }
            });
            navigator.mediaSession.setActionHandler('pause', function () {
                if (window.backupControl) {
                    switchPlay();
                } else {
                    player.pause();
                }
            });
            navigator.mediaSession.setActionHandler('nexttrack', function () {
                playNext();
            });
        }
        const makeItem = (name, info, avatar, menuCallback, redDot) => {
            let newItem = document.createElement("li");
            newItem.className = "mdc-list-item";
            newItem.tabIndex = "-1";
            let rippleSpan = document.createElement("span");
            rippleSpan.className = "mdc-list-item__ripple";
            newItem.appendChild(rippleSpan);
            let avatarSpan = document.createElement("span");
            avatarSpan.className = "mdc-list-item__graphic";
            let imgItem = document.createElement("img");
            if (avatar.indexOf(".hdslb.") > 0) {
                avatar = avatar.replace("@.avif", "@120h.avif")
            };
            imgItem.src = avatar;
            imgItem.crossOrigin = "anonymous";
            imgItem.loading = "lazy";
            imgItem.alt = name;
            imgItem.style = "object-fit: cover;border-radius: 4px;height: 100%;width: 100%;opacity:0;transition: opacity 0.5s;";
            imgItem.onload = () => {
                imgItem.style.opacity = 1;
            }
            avatarSpan.appendChild(imgItem);
            newItem.appendChild(avatarSpan);
            let textSpan = document.createElement("span");
            textSpan.className = "mdc-list-item__text";
            let nameSpan = document.createElement("span");
            nameSpan.className = "mdc-list-item__primary-text";
            nameSpan.innerText = name;
            textSpan.appendChild(nameSpan);
            let infoSpan = document.createElement("span");
            infoSpan.className = "mdc-list-item__secondary-text";
            infoSpan.innerText = info;
            textSpan.appendChild(infoSpan);
            newItem.appendChild(textSpan);
            if (menuCallback) {
                newItem.addEventListener("contextmenu", (event) => {
                    event.preventDefault();
                    menuCallback(event);
                });
                let menu = document.createElement("span");
                menu.className = "mdc-list-item__meta";
                let menuBtn = document.createElement("button");
                menuBtn.innerText = "more_vert"
                menuBtn.addEventListener("click", menuCallback);
                menuBtn.className = "mdc-icon-button material-icons";
                if (redDot) {
                    menuBtn.style.color = "red";
                };
                menu.appendChild(menuBtn);
                newItem.appendChild(menu);
            }
            return newItem;
        }
        const makeMenu = (text, icon) => {
            let menuItem = document.createElement("li");
            menuItem.style.userSelect = "all";
            menuItem.tabIndex = "-1";
            menuItem.oncontextmenu = () => { return false; };
            menuItem.className = "mdc-list-item";
            let ripple = document.createElement("span");
            ripple.className == "mdc-list-item__ripple";
            menuItem.appendChild(ripple);
            if (icon) {
                let iconItem = document.createElement("p");
                iconItem.style.backgroundImage = "url(" + icon + ")";
                iconItem.className = "mdc-list-item__graphic material-icons";
                menuItem.appendChild(iconItem);
            }
            let textItem = document.createElement("span");
            textItem.className = "mdc-list-item__text";
            textItem.style.display = "flex";
            textItem.innerHTML = text;
            menuItem.setSpan = text => {
                textItem.innerText = text;
            }
            menuItem.appendChild(textItem);
            return menuItem;
        }
        const saveImgMenu = (url, name) => {
            menuList.innerHTML = "";
            let imgItem = document.createElement("img");
            imgItem.src = url;
            imgItem.crossOrigin = "anonymous";
            imgItem.style = "max-height:0px;width:100%;height:auto;object-fit:cover;border-radius: 5px 5px 0px 0px;opacity:0;transition: opacity 0.5s, max-height 0.1s;";
            imgItem.onload = async () => {
                imgItem.style.opacity = 1;
                imgItem.style.maxHeight = "calc(80vh - 96px)";
                await sleep(100);
                imgItem.setAttribute("loaded", "true");
            }
            menuList.appendChild(imgItem);
            let saveMenu = makeMenu("保存图片", "./img/save.svg");
            saveMenu.addEventListener("click", async (e) => {
                //保存图片
                e.stopPropagation();
                saveMenu.setSpan("正在保存...");
                dlFile(URL.createObjectURL(await (await fetch(url, {
                    mode: "cors"
                })).blob()), name + "_封面.avif");
                hideMenu();
            });
            menuList.appendChild(saveMenu);
            if (navigator.share) {
                let shareMenu = makeMenu("分享图片", "./img/share.svg");
                shareMenu.addEventListener("click", async (e) => {
                    //保存图片
                    e.stopPropagation();
                    shareMenu.setSpan("正在准备分享...");
                    navigator.share({
                        title: name + "封面",
                        text: "我正在用545在线(545.qinlili.bid)分享给你塔宝的" + name + "封面图片",
                        url: "https://545.qinlili.bid",
                        files: [new File([await (await fetch(url, {
                            mode: "cors"
                        })).blob()], name + "_封面.avif", {
                            type: "image/avif"
                        })]
                    });
                    hideMenu();
                });
                menuList.appendChild(shareMenu);
            }
            const list = new MDCList(menuList);
            const listItemRipples = list.listElements.map((listItemEl) => new MDCRipple(listItemEl));
            showMenu();
        }
        const loadMenu = text => {
            let loadDiv = document.createElement("div");
            loadDiv.style = "display:flex;flex-direction:row;text-align:center;width:100%;justify-content: space-around;";
            let loadSvg = document.createElement("img");
            loadSvg.src = "./img/loading.webp";
            loadSvg.style = "width:32px;height:32px;padding:0px;";
            loadDiv.appendChild(loadSvg);
            let loadText = document.createElement("p");
            loadText.className = "tips32";
            loadText.innerText = text;
            loadDiv.appendChild(loadText);
            loadDiv.setText = text => {
                loadText.innerText = text;
            }
            return loadDiv;
        }
        const makeSongMenu = songInfo => {
            if (!window.isBiliLite) {
                let dlMenu = makeMenu("下载", "./img/download.svg");
                dlMenu.addEventListener("click", async () => {
                    setStatus("正在下载" + songInfo.name, true);
                    let playBlob = URL.createObjectURL(await (await fetch(songInfo.url[cdn])).blob());
                    dlFile(playBlob, songInfo.name + ".ogg");
                    setStatus("下载" + songInfo.name + "成功", false);
                });
                menuList.appendChild(dlMenu);
                if (songInfo.hi_res_id) {
                    let dlHiMenu = makeMenu("下载Hi-Res FLAC", "./img/download.svg");
                    dlHiMenu.addEventListener("click", async () => {
                        window.open("https://ctfile.qinlili.bid/?file=" + songInfo.hi_res_id + "&pass=547873715");
                    });
                    menuList.appendChild(dlHiMenu);
                }
            }
            let coverMenu = makeMenu("查看封面", "./img/cover.svg");
            coverMenu.addEventListener("click", (event) => {
                event.stopPropagation();
                saveImgMenu(songInfo.cover, songInfo.name);
            });
            menuList.appendChild(coverMenu)
            let goMenu = makeMenu("查看原始投稿" + (songInfo.is4k ? `<span class="material-icons">4k</span>` : ""), "./img/link.svg");
            goMenu.id = "goMenu";
            goMenu.addEventListener("click", () => {
                window.open(songInfo.origin, "_blank")
            });
            menuList.appendChild(goMenu);
            if (!window.isBiliLite) {
                let shareMenu = makeMenu("分享", "./img/share.svg");
                shareMenu.addEventListener("click", () => {
                    shareSong(songInfo);
                });
                menuList.appendChild(shareMenu);
            }
            let qualityMenu = makeMenu("播放音质:" + songInfo.quality, "./img/audiofile.svg");
            let playQuality = true;
            qualityMenu.addEventListener("click", (event) => {
                event.stopPropagation();
                let btn = event.currentTarget;
                let text = btn.querySelector(".mdc-list-item__text");
                text.innerText = playQuality ? "原始音质:" + songInfo.source_quality : "播放音质:" + songInfo.quality;
                playQuality = !playQuality;
            });
            menuList.appendChild(qualityMenu);
            let timeMenu = makeMenu("发布时间:" + songInfo.release_date, "./img/calendar.svg");
            menuList.appendChild(timeMenu);
            const list = new MDCList(menuList);
            const listItemRipples = list.listElements.map((listItemEl) => new MDCRipple(listItemEl));
        }
        const shareSong = async songInfo => {
            if (navigator.share) {
                if (window.fileShare) {
                    setStatus("准备分享的文件", true);
                    let file = new File([await (await fetch(songInfo.url[cdn])).blob()], songInfo.name + ".ogg", {
                        type: "audio/ogg"
                    })
                    setStatus("发起分享", true);
                    navigator.share({
                        title: songInfo.name,
                        text: "我正在用545在线(545.qinlili.bid)分享给你塔宝的" + songInfo.name,
                        url: "https://545.qinlili.bid",
                        files: [file]
                    });
                } else {
                    navigator.share({
                        title: "545在线",
                        text: "我正在用545在线(545.qinlili.bid)收听塔宝的" + songInfo.name + "，你可以点击此链接直接在线播放" + songInfo.url[cdn] + " 或使用545在线更方便的省流量播放",
                        url: "https://545.qinlili.bid"
                    });
                }
                setStatus("分享成功", false);
            } else {
                alert("你使用的浏览器不支持分享");
            }
        };
        const getAudioList = async () => {
            let jsonData = await (await fetch("audioInfo.json?ForceNoCache=1")).json()
            if (jsonData && jsonData.success) {
                return jsonData.songs;
            }
            return false;
        }
        const renderAudioList = async () => {
            console.log(window.audioList);
            //渲染全部歌单
            const audioFolderModule = document.getElementById("audioFolderModule");
            const audioFilesModule = document.getElementById("audioFilesModule");
            const switchListDisplay = async (type) => {
                if (window.switchQueue) {
                    await sleep(250);
                    return switchListDisplay(type);
                }
                window.switchQueue = true;
                switch (type) {
                    default:
                    case 0: {
                        audioFilesModule.style.transform = "scale(0,1)";
                        audioFolderModule.style.display = "block";
                        await sleep(5);
                        audioFolderModule.style.transform = "scale(1,1)";
                        await sleep(200);
                        audioFilesModule.style.display = "none";
                        audioFilesModule.innerHTML = "";
                        if (window.CloseWatcher) {
                            window.FolderBack.destroy();
                        }
                        break;
                    };
                    case 1: {
                        audioFolderModule.style.transform = "scale(0,1)";
                        audioFilesModule.style.display = "block";
                        await sleep(5);
                        audioFilesModule.style.transform = "scale(1,1)";
                        await sleep(200);
                        audioFolderModule.style.display = "none";
                        if (window.CloseWatcher) {
                            window.FolderBack = new CloseWatcher();
                            FolderBack.onclose = () => {
                                switchListDisplay(0);
                            };
                        }
                        break;
                    };
                }
                window.switchQueue = false;
            }
            audioFolderModule.innerHTML = "";
            if (devMode) {
                //开启隐藏终端模式
                let terminalItem = makeItem("韭菜盒子", "运行一些能补充营养的指令", "./img/ottobox.svg");
                audioFolderModule.insertAdjacentElement("afterbegin", terminalItem);
                terminalItem.addEventListener("click", async () => {
                    //处理终端命令
                    let command = prompt("太监传话");
                    if (command == null) {
                        return;
                    }
                    switch (command) {
                        case "addSong":
                            {
                                let songInfo = prompt("输入符合格式的歌曲信息");
                                try {
                                    addToPlayList(JSON.parse(songInfo));
                                } catch (e) {
                                    alert("解析失败");
                                }
                                break;
                            };
                        default:
                            {
                                alert("营养缺失了")
                                break;
                            }
                    }
                });
            }
            let searchItem = makeItem("搜索", "上一次歌单更新:" + localStorage.lastSongUpdate, "./img/search.svg");
            searchItem.addEventListener("click", () => {
                let searchValue = prompt("请输入关键字，支持歌名/完整标题\n留空为显示全部歌曲");
                if (searchValue == null) {
                    return;
                };
                let backItem = makeItem("...", "返回歌单列表", "./img/folder.svg")
                audioFilesModule.appendChild(backItem);
                backItem.addEventListener("click", () => {
                    switchListDisplay(0);
                })
                //逐一匹配
                window.audioList.forEach(folderInfo => {
                    folderInfo.list.forEach(songInfo => {
                        if ((songInfo.name.indexOf(searchValue) >= 0) || (songInfo.full_title.indexOf(searchValue) >= 0)) {
                            let song = makeItem(songInfo.name, songInfo.full_title, songInfo.cover, (event) => {
                                //歌曲菜单
                                event.stopPropagation();
                                menuList.innerHTML = "";
                                makeSongMenu(songInfo);
                                showMenu();
                            });
                            song.addEventListener("click", () => {
                                addToPlayList(songInfo);
                            })
                            audioFilesModule.appendChild(song);
                        }
                    })
                })
                const list = new MDCList(audioFilesModule);
                const listItemRipples = list.listElements.map((listItemEl) => new MDCRipple(listItemEl));
                switchListDisplay(1);
            });
            audioFolderModule.appendChild(searchItem);
            window.audioList.forEach(folderInfo => {
                //分类渲染
                let folder = makeItem(folderInfo.type, folderInfo.description, "./img/folder.svg", (event) => {
                    //文件夹菜单
                    event.stopPropagation();
                    menuList.innerHTML = "";
                    let addMenu = makeMenu("全部添加到播放列表", "./img/addlist.svg");
                    addMenu.addEventListener("click", () => {
                        if (!window.list) {
                            window.list = [];
                        }
                        folderInfo.list.forEach(song => {
                            window.list.push(song);
                        });
                        window.list = window.list.filter((value, index, self) =>
                            index === self.findIndex((t) => (
                                t.place === value.place && t.name === value.name
                            ))
                        )
                        localStorage.playList = JSON.stringify(window.list);
                        renderPlayList();
                    });
                    menuList.appendChild(addMenu);
                    const list = new MDCList(menuList);
                    const listItemRipples = list.listElements.map((listItemEl) => new MDCRipple(listItemEl));
                    showMenu();
                });
                audioFolderModule.appendChild(folder);
                folder.addEventListener("click", () => {
                    //展开文件夹
                    let backItem = makeItem("...", "返回上一级目录", "./img/folder.svg")
                    audioFilesModule.appendChild(backItem);
                    backItem.addEventListener("click", () => {
                        switchListDisplay(0)
                    })
                    //渲染子项目
                    folderInfo.list.forEach(songInfo => {
                        let song = makeItem(songInfo.name, songInfo.full_title, songInfo.cover, (event) => {
                            //歌曲菜单
                            event.stopPropagation();
                            menuList.innerHTML = "";
                            makeSongMenu(songInfo);
                            showMenu();
                        });
                        song.addEventListener("click", () => {
                            addToPlayList(songInfo);
                        })
                        audioFilesModule.appendChild(song);
                    })
                    switchListDisplay(1);
                })
            })
            const list = new MDCList(audioFolderModule);
            const listItemRipples = list.listElements.map((listItemEl) => new MDCRipple(listItemEl));
        }
        const renderPlayList = () => {
            const currentDate = new Date();
            const empty = () => {
                audioListModule.innerHTML = "";
                document.getElementById("empty").style.display = "block";
            }
            if (localStorage.playList) {
                if (JSON.parse(localStorage.playList).length) {
                    //渲染播放列表
                    document.getElementById("empty").style.display = "none";
                    window.list = JSON.parse(localStorage.playList);
                    const audioListModule = document.getElementById("audioListModule");
                    audioListModule.style.display = "none";
                    audioListModule.innerHTML = "";
                    window.list.forEach(songInfo => {
                        let needRed = false
                        if (songInfo.official) {
                            let releaseDate = songInfo.release_date.split("-");
                            let compareDate = new Date(releaseDate[0], releaseDate[1] - 1, releaseDate[2]);
                            let far = (currentDate.getTime() - compareDate.getTime()) / 86400000;
                            if (far < 14 && !songInfo.viewed) {
                                needRed = true;
                            }
                        };
                        let song = makeItem(songInfo.name, songInfo.full_title, songInfo.cover, (event) => {
                            //歌曲菜单
                            event.stopPropagation();
                            menuList.innerHTML = "";
                            let deleteMenu = makeMenu("从播放列表里删除", "./img/delete.svg");
                            deleteMenu.addEventListener("click", async () => {
                                if (confirm("你想要从播放列表删除 " + songInfo.name + " 吗？")) {
                                    removeFromPlayList(songInfo);
                                }
                            });
                            menuList.appendChild(deleteMenu);
                            makeSongMenu(songInfo);
                            if (needRed) {
                                let goMenu = document.getElementById("goMenu");
                                goMenu.style.backgroundColor = "wheat";
                                goMenu.getElementsByClassName("mdc-list-item__text")[0].innerText = "去给塔宝一键三连";
                                goMenu.addEventListener("click", () => {
                                    songInfo.viewed = true;
                                    localStorage.playList = JSON.stringify(window.list);
                                })

                            }
                            showMenu();
                        }, needRed);
                        song.addEventListener("click", () => {
                            //立即播放
                            playNow(songInfo);
                        })
                        audioListModule.appendChild(song);
                    })
                    const list = new MDCList(audioListModule);
                    const listItemRipples = list.listElements.map((listItemEl) => new MDCRipple(listItemEl));
                    audioListModule.style.display = "block";
                } else {
                    empty();
                }
            } else {
                empty();
            }
        }
        const addToPlayList = song => {
            setStatus("已添加到播放列表:" + song.name, false);
            if (!window.list) {
                window.list = [];
            }
            window.list.push(song);
            window.list = window.list.filter((value, index, self) =>
                index === self.findIndex((t) => (
                    t.place === value.place && t.name === value.name
                ))
            )
            localStorage.playList = JSON.stringify(window.list);
            renderPlayList();
        }
        const removeFromPlayList = song => {
            setStatus("已移除播放列表:" + song.name, false);
            window.list.forEach((info, index) => {
                if (info == song) {
                    window.list.splice(index, 1)
                }
            });
            localStorage.playList = JSON.stringify(window.list);
            renderPlayList();
        }
        const playNow = async song => {
            document.title = song.name + "-545在线";
            window.currentPlay = song.name;
            if (window.castSwitch) {
                ignoreNextCastEnd = true;
                document.getElementById("castBtn").className = "topBtn breath";
                cjsplay.cast(song.url[cdn], {
                    poster: song.cover.replace(".avif", ".webp"),
                    title: song.name,
                    description: "连续播放需保持页面开启"
                });
                localStorage.lastPlay = JSON.stringify(song);
                return;
            }
            setStatus("正在下载" + song.name, true);
            let playBlob = await (await fetch(song.url[cdn]).catch(error => {
                setStatus("下载失败" + song.name, false);
                if (!navigator.onLine) {
                    //断网跳过未下载歌曲
                    player.dispatchEvent(new CustomEvent("ended"));
                } else {
                    playNow(song);
                }
            })).blob();
            if (window.currentPlay == song.name) {
                if (window.codecBoost) {
                    setStatus("解码音频中", true);
                    if (!window.audioCtx) {
                        window.audioCtx = new AudioContext();
                    }
                    let decodeBuffer = await window.audioCtx.decodeAudioData(await playBlob.arrayBuffer());
                    let source = audioCtx.createBufferSource();
                    if (window.currentSource) {
                        window.currentSource.disconnect(window.audioCtx.destination);
                    }
                    window.currentSource = source;
                    source.buffer = decodeBuffer;
                    source.connect(window.audioCtx.destination);
                    source.start(0);
                    document.getElementById("playBtn").className = (audioCtx.state == "running") ? "topBtn active" : "topBtn";
                    source.onended = () => {
                        player.dispatchEvent(new CustomEvent("ended"));
                    }
                    setStatus(song.name, false);
                    localStorage.lastPlay = JSON.stringify(song);
                } else {
                    player.src = URL.createObjectURL(playBlob);
                    if (window.wasmPlayer) {
                        player.play();
                    } else {
                        player.play().catch(() => { "Need user action first." });
                    }
                    setStatus(song.name, false);
                    localStorage.lastPlay = JSON.stringify(song);
                }
            };
            if ('mediaSession' in navigator) {
                navigator.mediaSession.metadata = new MediaMetadata({
                    title: song.name,
                    artist: "帅比笙歌超可爱OvO",
                    album: "545在线",
                    artwork: [{
                        sizes: "320x180",
                        src: song.cover,
                        type: "image/avif"
                    }]
                });
            };
        }
        //恢复播放
        const recoverPlay = () => {
            if (localStorage.lastPlay) {
                let song = JSON.parse(localStorage.lastPlay)
                playNow(song);
            }
        }
        const playNext = () => {
            //随机播放下一首
            const getRandom = () => {
                let num;
                let randomMethod = localStorage.randomMethod || "default";
                switch (randomMethod) {
                    case "real":
                        {
                            //crypto真随机
                            break;
                        };
                    case "list":
                        {
                            //队列随机
                            if (window.order && window.order.length) {
                                num = window.order.pop();
                            } else {
                                //生成随机列表
                                let listLength = window.list.length;
                                let tempArray = []
                                let order = [];
                                for (let i = 0; i < listLength; i++) {
                                    tempArray[i] = i;
                                };
                                for (let i = 0; i < listLength; i++) {
                                    let pick = random(0, tempArray.length - 1)
                                    order[i] = tempArray[pick];
                                    tempArray.splice(pick, 1)
                                }
                                window.order = order;
                                console.log("生成了新的播放列表");
                                console.log(order);
                                num = window.order.pop();
                            }
                            break;
                        };
                    case "exclude":
                        {
                            //就近排除
                            break;
                        };
                    case "default":
                    default:
                        {
                            num = random(0, window.list.length - 1)
                            break;
                        }
                }
                return num;
            }
            playNow(window.list[getRandom()]);
        }
        const patchEnd = () => {
            player.addEventListener("ended", () => {
                if (repeatSwitch) {
                    let song = JSON.parse(localStorage.lastPlay);
                    playNow(song);
                    return;
                }
                if (shuffleSwitch) {
                    playNext();
                }
            })
        };
        const functionMenu = () => {
            menuList.innerHTML = "";
            //功能菜单
            if (window.castSwitch) {
                let castMenu = makeMenu("停止Chromecast", "./img/cast.svg");
                castMenu.addEventListener("click", () => {
                    cjsplay.disconnect();
                });
                menuList.appendChild(castMenu);
            }
            let sleepMenu = makeMenu("睡眠模式", "./img/sleep.svg");
            sleepMenu.addEventListener("click", () => {
                let time = prompt("入睡需要多少时间捏？(单位：分钟，请输入一个整数，小数点后会被忽略)");
                if (time == null || parseInt(time) == NaN) {
                    alert("你没有输入有效数值");
                    return;
                };
                alert("睡眠模式已启用！\n将在" + time + "分钟后停止播放");
                setTimeout(() => {
                    if (window.backupControl) {
                        if (window.wasmPlayer) {
                            document.querySelector("#player").pause();
                        };
                        if (window.codecBoost) {
                            if (window.audioCtx) {
                                window.audioCtx.suspend();
                            }
                        };
                    } else {
                        player.pause();
                    };
                    menuList.innerHTML = "";
                    let imgItem = document.createElement("img");
                    imgItem.src = "./img/wanan.png";
                    imgItem.style = "height:256px;width:100%;object-fit:contain;border-radius: 5px 5px 0px 0px;";
                    menuList.appendChild(imgItem);
                    let textTip = document.createElement("p");
                    textTip.innerText = "545晚安好梦，塔宝陪你做个梦";
                    textTip.style = "width:100%;text-align:center;"
                    menuList.appendChild(textTip);
                    showMenu();
                }, parseInt(time) * 60000)
            })
            menuList.appendChild(sleepMenu);
            if (window.innerWidth > window.innerHeight && window.innerHeight > 600 && window.self === window.top && !window.isBiliLite) {
                let wallpaperMenu = makeMenu("壁纸模式", "./img/fullscreen.svg");
                wallpaperMenu.addEventListener("click", event => {
                    document.location.href = './plugins/loader?name=wallpaper';
                });
                menuList.appendChild(wallpaperMenu);
            };
            let toolMenu = makeMenu("工具箱", "./img/tool.svg");
            toolMenu.addEventListener("click", () => {
                bottomdown();
                document.location.href = './tools';
            });
            menuList.appendChild(toolMenu);
            let historyMenu = makeMenu("看录播", "./img/history.svg");
            historyMenu.addEventListener("click", async e => {
                bottomdown();
                document.location.href = './plugins/loader?name=record';
            });
            menuList.appendChild(historyMenu);
            let navMenu = makeMenu("导航", "./img/nav.svg");
            navMenu.addEventListener("click", async (e) => {
                bottomdown();
                document.location.href = './plugins/loader?name=navigate';
            });
            menuList.appendChild(navMenu);
            let settingMenu = makeMenu("设置", "./img/setting.svg");
            settingMenu.addEventListener("click", () => {
                bottomdown();
                document.location.href = './settings';
            });
            menuList.appendChild(settingMenu);
            if (!(window.self === window.top)) {
                let exitMenu = makeMenu("退出壁纸模式", "./img/exit.svg");
                exitMenu.addEventListener("click", () => {
                    window.parent.postMessage("exit", "*");
                })
                menuList.appendChild(exitMenu);
            }
            if ((history.length == 1 || navigator.userAgent === "545LocalPlayer") && window.self === window.top) {
                let exitMenu = makeMenu("退出", "./img/exit.svg");
                exitMenu.addEventListener("click", () => {
                    window.close();
                })
                menuList.appendChild(exitMenu);
            };
            const list = new MDCList(menuList);
            const listItemRipples = list.listElements.map((listItemEl) => new MDCRipple(listItemEl));
            showMenu();
        }
        if (!navigator.serviceWorker) {
            alert("你的浏览器不支持Service Worker，你应该换个浏览器了");
        }
        if (navigator.userAgent.indexOf("WOW64") > 1 && window.self === window.top) {
            alert(window.isBiliLite ? "为什么你要在64位操作系统上装32位的BiliLite？" : "你正在64位操作系统上使用32位浏览器!为了更快的访问速度请改用64位浏览器!");
        }
        if (navigator.serviceWorker && !navigator.serviceWorker.controller) {
            (async () => {
                setStatus("正在安装Service Worker", true);
                await navigator.serviceWorker.register('./sw.js', {
                    scope: '/'
                });
                setStatus("安装成功，片刻后生效", true);
            })();
        }
        //检测直播
        if (window.self === window.top) {
            (async () => {
                await sleep(100)
                if (localStorage.livePush && JSON.parse(localStorage.livePush)) {
                    if (Notification.permission == "default") {
                        await Notification.requestPermission();
                    };
                    const detectLive = async () => {
                        if (window.isBiliLite) {
                            return false;
                        }
                        let time = new Date().getHours() + (new Date().getTimezoneOffset() / 60 + 8);
                        if (time < 0) {
                            time += 24;
                        }
                        let liveStatus = await (await fetch((navigator.userAgent === "545LocalPlayer") ? "http://127.0.0.1:60510/https://api.live.bilibili.com/bili/living_v2/15641218" : "https://biliapi.qinlili.bid/status?uid=15641218&ForceNoCache=1").catch(error => { })).json();
                        if (liveStatus.data && (liveStatus.data.status == 1)) {
                            navigator.serviceWorker.ready.then(function (registration) {
                                registration.showNotification('塔宝正在直播！', {
                                    body: '赶紧去直播间补充塔能量吧',
                                    badge: './icon_mono.png',
                                    icon: './icon.webp',
                                    tag: clientLive ? '直播推送客户端' : '直播推送'
                                });
                            });
                        } else {
                            await sleep(300000);
                            detectLive();
                        }
                    };
                    detectLive();
                };
            })();
        };
        setStatus("就绪");
        document.title = "545在线";
        if (window.CloseWatcher) {
            const createWatcher = () => {
                window.WindowBack = new CloseWatcher();
                WindowBack.onclose = () => {
                    setTempStatus("2秒内再按一次返回退出", 2000);
                    setTimeout(createWatcher, 2000);
                };
            }
            createWatcher();
        }
        if (!window.wasmPlayer && !window.codecBoost && window.self === window.top) {
            recoverPlay();
        }

        patchEnd();
        const updatePlayList = () => {
            let allSongs = [];
            window.audioList.forEach(folder => {
                allSongs = allSongs.concat(folder.list);
            });
            let newList = [];
            if (window.list.length > 0) {
                window.list.forEach(song => {
                    let newSong = allSongs.find(s => { return s.name == song.name && s.release_date == song.release_date });
                    if (!newSong) {
                        newSong = song;
                    };
                    if (song.viewed) { newSong.viewed = song.viewed };
                    newList.push(newSong);
                });
                window.list = newList;
            }
            localStorage.playList = JSON.stringify(window.list);
            renderPlayList();
        };
        renderPlayList();
        if (!localStorage.cacheSong) {
            getAudioList().then(songs => {
                if (songs) {
                    localStorage.cacheSong = JSON.stringify(songs);
                    localStorage.lastSongUpdate = new Date().toLocaleDateString();
                    window.audioList = songs;
                    updatePlayList();
                    renderAudioList();
                } else {
                    alert("读取歌单失败！");
                }
            })
        } else {
            window.audioList = JSON.parse(localStorage.cacheSong);
            renderAudioList();
            if (localStorage.lastSongUpdate == new Date().toLocaleDateString()) { } else {
                getAudioList().then(songs => {
                    if (songs) {
                        localStorage.cacheSong = JSON.stringify(songs);
                        localStorage.lastSongUpdate = new Date().toLocaleDateString();
                        window.audioList = songs;
                        updatePlayList();
                        renderAudioList();
                    }
                })
            };
        };
        (() => {
            if (devMode) {
                let script = document.createElement('script');
                script.src = "https://lib.baomitu.com/eruda/2.4.1/eruda.min.js";
                document.body.appendChild(script);
                script.onload = function () {
                    eruda.init()
                }
            }
        })();
    </script>
</body>

</html>